简介:The Neo4j Graph Algorithms User Guide v3.5

1.简介

algo是Neo4j的一个插件包,类似apoc,提供了丰富的图算法,适合处理数据量较大、网络比较复杂的图结构。图算法用于计算图形,节点或关系的度量。可以提供图中相关实体(中心,排名)或社区(社区检测,图分区,聚类)等固有结构的计算。

github地址: https://github.com/neo4j-contrib/neo4j-graph-algorithms/releases
文档地址:https://neo4j.com/docs/graph-algorithms/current/

1.1 算法

1.1.1中心性

这些算法确定网络中不同节点的重要性:

  • PageRank(algo.pageRank)
  • 中介中心(algo.betweenness)
  • 亲近中心(algo.closeness)
  • 调和中心(algo.closeness.harmonic)

1.1.2社区发现

这些算法评估群组的聚集或分区方式,以及它们加强或分裂的趋势:

  • louvain(algo.louvain)
  • 标签传播(algo.labelPropagation)
  • 连接分量(algo.unionFind)
  • 强连接分量(algo.scc)
  • 三角计数/聚类系数(algo.triangleCount)

1.1.3路径探索

这些算法有助于找到最短路径或评估路径的可用性和质量:

  • 最小权重生成树(algo.mst)
  • 最短路径(algo.shortestPath)
  • 单源最短路径(algo.shortestPath)
  • 所有节点对之间的最短路径(algo.allShortestPaths)
  • A *(algo.shortestPath.astar)
  • K条最短路径算法(algo.kShortestPaths)
  • 随机漫步(algo.randomWalk)

1.1.4相似性

这些算法有助于计算节点的相似性:

  • Jaccard相似度(algo.similarity.jaccard)
  • 余弦相似度(algo.similarity.cosine)
  • 欧几里德距离(algo.similarity.euclidean)
  • 重叠相似性(algo.similarity.overlap)

1.1.5预处理

  • One Hot Encoding (algo.ml.oneHotEncoding)

1.2 安装

1.下载 graph-algorithms-algo-[version].jar

2.复制到 $NEO4J_HOME/plugins 目录里

3.打开$NEO4J_HOME/conf/neo4j.conf文件,加上:

1
dbms.security.procedures.unrestricted=algo.*

4.重启数据库

5.测试:查看所有算法

1
CALL algo.list()

1.3 使用

这些图算法都是neo4j的存储过程,可直接用cypher语句在图浏览器里调用
对于大多数算法, 主要有以下两个存储过程格式:

1
algo.<name>

  • 此过程将结果作为节点属性写回图表,并报告统计信息。

    1
    algo.<name>.stream
  • 此过程返回数据流。例如,node-id和计算值。

对于大型图形,流式传输过程可能会返回数百万甚至数十亿的结果。在这种情况下,存储算法的结果可能更方便,然后在以后的查询中使用它们。

可以使用标签和关系类型投影或cypher投影来投影我们想要运行算法的图形。投影图模型与Neo4j存储的图模型分开,以实现图的拓扑的快速缓存,仅包含相关的节点,关系和权重。
img
PS:投影图模型不支持单对节点之间的多个关系。在投影期间,在定向情况下仅允许每个方向(in,out)的一对节点之间的一个关系,但是对于无向情况允许有两个关系。

1.3.1标签和关系型投影

使用label参数和关系类型来描述节点和关系,投影想要运行算法的子图
通用调用语法是:

1
CALL algo.<name>('NodeLabel', "RelationshipType", {config})

例如,DBpedia上的PageRank(11M节点,116M关系):

1
2
3
4
5
6
7
CALL algo.pageRank('Page','Link',{iterations:5, dampingFactor:0.85, write: true, writeProperty:'pagerank'});
// YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, write, writeProperty

CALL algo.pageRank.stream('Page','Link',{iterations:5, dampingFactor:0.85})
YIELD node, score
RETURN node.title, score
ORDER BY score DESC LIMIT 10;

1.3.1.1大图投影

默认标签和关系类型投影具有20亿个节点和20亿个关系的限制,因此如果我们的项目图形大于此,我们需要使用巨大的图形投影。可以通过 graph:’huge’ 在配置中进行设置来启用此功能。
通用调用语法是:

1
CALL algo.<name>('NodeLabel', "RelationshipType", {graph: "huge"})

例如,DBpedia上的PageRank:

1
2
CALL algo.pageRank('Page','Link',{iterations:5, dampingFactor:0.85, writeProperty:'pagerank',graph:'huge'});
YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, writeProperty

1.3.2 Cypher投影

如果标签和关系类型投影不能描述运行算法的子图,我们可以使用Cypher语句来投影图的子集。使用node-statement而不是label参数和relationship-statement而不是relationship-type,并在config中使用设置 graph:’cypher’ 。

只有在node-statement中描述了源节点和目标节点时,才会预测relationship-statement中描述的关系。将忽略node-statement中描述的既没有源节点和目标节点的关系。

除了这些语句中的ID之外,我们还可以返回属性值或权重(根据我们的配置)。

Cypher投影使我们在描述我们想要分析的子图时更具表现力,但可能需要更长的时间来使用更复杂的cypher查询来投影图。

通用调用语法是:

1
2
3
4
CALL algo.<name>(
'MATCH (n) RETURN id(n) AS id',
"MATCH (n)-->(m) RETURN id(n) AS source, id(m) AS target",
{graph: "cypher"})

例如,DBpedia上的PageRank:

1
2
3
4
CALL algo.pageRank(
'MATCH (p:Page) RETURN id(p) as id',
'MATCH (p1:Page)-[:Link]->(p2:Page) RETURN id(p1) as source, id(p2) as target',
{graph:'cypher', iterations:5, write: true});

Cypher投影也可用于投影虚拟(非存储)图形。下面是一个示例,说明如何使用人与人之间共同访问的网页数量作为关系权重,投影访问相同网页的人的无向图并在其上运行Louvain社区检测算法。

1
2
3
4
5
CALL algo.louvain(
'MATCH (p:Person) RETURN id(p) as id',
'MATCH (p1:Person)-[:Visit]->(:Page)<-[:Visit]-(p2:Person)
RETURN id(p1) as source, id(p2) as target, count(*) as weight',
{graph:'cypher', iterations:5, write: true});

1.4 图加载

由于将大型图形加载到算法数据结构中可能需要一些时间,因此可以预先加载图形,然后通过名称为多个图形算法引用它们。使用后,可以从内存中删除它们以释放使用的资源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Load graph
CALL algo.graph.load('my-graph','Label','REL_TYPE',{graph:'heavy',..other config...})
YIELD name, graph, direction, undirected, sorted, nodes, loadMillis, alreadyLoaded,
nodeWeight, relationshipWeight, nodeProperty, loadNodes, loadRelationships;

// Info on loaded graph
CALL algo.graph.info('my-graph')
YIELD name, type, exists, removed, nodes;

// Use graph
CALL algo.pageRank(null,null,{graph:'my-graph',...})


// Remove graph
CALL algo.graph.remove('my-graph')
YIELD name, type, exists, removed, nodes;